using System;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using TenantManagementService.Tenants;
using TenantManagementService.Monitoring;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.MultiTenancy;

namespace TenantManagementService
{
    [ConnectionStringName("Default")]
    public class TenantManagementDbContext : AbpDbContext<TenantManagementDbContext>
    {
        public DbSet<Tenant> Tenants { get; set; } = null!;
        public DbSet<TenantManagementService.Tenants.TenantConfiguration> TenantConfigurations { get; set; } = null!;
        public DbSet<MonitoringMetric> MonitoringMetrics { get; set; } = null!;
        public DbSet<MonitoringMetricValue> MonitoringMetricValues { get; set; } = null!;
        public DbSet<AlertRule> AlertRules { get; set; } = null!;
        public DbSet<Alert> Alerts { get; set; } = null!;

        public TenantManagementDbContext(DbContextOptions<TenantManagementDbContext> options)
            : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.ConfigureTenantManagement();
        }
    }

    public static class TenantManagementDbContextModelCreatingExtensions
    {
        public static void ConfigureTenantManagement(this ModelBuilder builder)
        {
            // 配置Tenant实体
            builder.Entity<Tenant>(b =>
            {
                b.ToTable("TenantManagementTenants", "Matrix");

                b.ConfigureByConvention();

                // 配置属性
                b.Property(x => x.Code)
                    .IsRequired()
                    .HasMaxLength(64);

                b.Property(x => x.Name)
                    .IsRequired()
                    .HasMaxLength(200);

                b.Property(x => x.Description)
                    .HasMaxLength(1000);

                b.Property(x => x.Type)
                    .HasConversion<int>();

                b.Property(x => x.Status)
                    .HasConversion<int>();

                b.Property(x => x.LogoUrl)
                    .HasMaxLength(500);

                b.Property(x => x.ThemeSettings)
                    .HasMaxLength(4000);

                b.Property(x => x.ConnectionString)
                    .HasMaxLength(2000);

                b.Property(x => x.Host)
                    .HasMaxLength(500);

                b.Property(x => x.AdminEmail)
                    .HasMaxLength(200);

                b.Property(x => x.AdminPhoneNumber)
                    .HasMaxLength(50);

                b.Property(x => x.MaxUserCount)
                    .HasDefaultValue(100);

                b.Property(x => x.CurrentUserCount)
                    .HasDefaultValue(0);

                b.Property(x => x.MaxStorageSize)
                    .HasDefaultValue(1024);

                b.Property(x => x.CurrentStorageUsage)
                    .HasDefaultValue(0);

                b.Property(x => x.Settings)
                    .HasMaxLength(4000);

                b.Property(x => x.FeatureSwitches)
                    .HasMaxLength(2000);

                b.Property(x => x.CustomProperties)
                    .HasMaxLength(4000);

                b.Property(x => x.ExtensionCount)
                    .HasDefaultValue(0);

                // 配置索引
                b.HasIndex(x => x.Code).IsUnique();
                b.HasIndex(x => x.Name);
                b.HasIndex(x => x.Type);
                b.HasIndex(x => x.Status);
                b.HasIndex(x => x.IsEnabled);
                b.HasIndex(x => x.AdminEmail);
                b.HasIndex(x => x.Host);
                b.HasIndex(x => x.SubscriptionEndTime);
                b.HasIndex(x => x.TrialEndTime);
                b.HasIndex(x => x.CreationTime);
                b.HasIndex(x => x.LastAccessTime);
                b.HasIndex(x => x.LastActivationTime);

                // 复合索引
                b.HasIndex(x => new { x.Status, x.IsEnabled });
                b.HasIndex(x => new { x.Type, x.Status });
                b.HasIndex(x => new { x.IsEnabled, x.SubscriptionEndTime });

                // Tenant实体不需要自引用关系配置
            });

            // 配置TenantConfiguration实体
            builder.Entity<TenantManagementService.Tenants.TenantConfiguration>(b =>
            {
                b.ToTable("TenantManagementConfigurations", "Matrix");

                b.ConfigureByConvention();

                // 配置属性
                b.Property(x => x.Key)
                    .IsRequired()
                    .HasMaxLength(200);

                b.Property(x => x.Value)
                    .IsRequired()
                    .HasMaxLength(4000);

                b.Property(x => x.Group)
                    .HasMaxLength(100);

                b.Property(x => x.Description)
                    .HasMaxLength(500);

                b.Property(x => x.Type)
                    .HasConversion<int>();

                b.Property(x => x.DefaultValue)
                    .HasMaxLength(4000);

                b.Property(x => x.ValidationRules)
                    .HasMaxLength(2000);

                // 配置索引
                b.HasIndex(x => x.TenantId);
                b.HasIndex(x => new { x.TenantId, x.Key }).IsUnique();
                b.HasIndex(x => x.Group);
                b.HasIndex(x => x.IsEncrypted);
                b.HasIndex(x => x.IsReadOnly);
                b.HasIndex(x => x.Type);

                // 关系配置
                b.HasOne<Tenant>()
                    .WithMany()
                    .HasForeignKey(x => x.TenantId)
                    .OnDelete(DeleteBehavior.Cascade);
            });

            // 配置监控指标实体
            builder.Entity<MonitoringMetric>(b =>
            {
                b.ToTable("MonitoringMetrics", "Matrix");

                b.ConfigureByConvention();

                b.Property(x => x.Name)
                    .IsRequired()
                    .HasMaxLength(200);

                b.Property(x => x.DisplayName)
                    .IsRequired()
                    .HasMaxLength(200);

                b.Property(x => x.Description)
                    .HasMaxLength(1000);

                b.Property(x => x.Type)
                    .HasConversion<int>();

                b.Property(x => x.Category)
                    .HasConversion<int>();

                b.Property(x => x.Unit)
                    .HasConversion<int>();

                b.Property(x => x.Labels)
                    .HasMaxLength(2000);

                // 配置索引
                b.HasIndex(x => x.Name);
                b.HasIndex(x => x.Category);
                b.HasIndex(x => x.Type);
                b.HasIndex(x => x.IsEnabled);
                b.HasIndex(x => new { x.Name, x.TenantId }).IsUnique();
            });

            // 配置监控指标值实体
            builder.Entity<MonitoringMetricValue>(b =>
            {
                b.ToTable("MonitoringMetricValues", "Matrix");

                b.ConfigureByConvention();

                b.Property(x => x.Value)
                    .HasPrecision(18, 6);

                b.Property(x => x.Dimensions)
                    .HasMaxLength(2000);

                b.Property(x => x.AggregationType)
                    .HasMaxLength(20);

                // 配置索引
                b.HasIndex(x => x.MetricId);
                b.HasIndex(x => x.Timestamp);
                b.HasIndex(x => new { x.MetricId, x.Timestamp });
                b.HasIndex(x => x.IsAggregated);

                // 关系配置
                b.HasOne<MonitoringMetric>()
                    .WithMany(m => m.MetricValues)
                    .HasForeignKey(x => x.MetricId)
                    .OnDelete(DeleteBehavior.Cascade);
            });

            // 配置告警规则实体
            builder.Entity<AlertRule>(b =>
            {
                b.ToTable("AlertRules", "Matrix");

                b.ConfigureByConvention();

                b.Property(x => x.Name)
                    .IsRequired()
                    .HasMaxLength(200);

                b.Property(x => x.DisplayName)
                    .IsRequired()
                    .HasMaxLength(200);

                b.Property(x => x.Description)
                    .HasMaxLength(1000);

                b.Property(x => x.MetricName)
                    .IsRequired()
                    .HasMaxLength(200);

                b.Property(x => x.Level)
                    .HasConversion<int>();

                b.Property(x => x.Operator)
                    .IsRequired()
                    .HasMaxLength(10);

                b.Property(x => x.Threshold)
                    .HasPrecision(18, 6);

                b.Property(x => x.LabelFilters)
                    .HasMaxLength(2000);

                b.Property(x => x.NotificationChannels)
                    .HasMaxLength(2000);

                b.Property(x => x.Expression)
                    .HasMaxLength(2000);

                // 配置索引
                b.HasIndex(x => x.Name);
                b.HasIndex(x => x.MetricName);
                b.HasIndex(x => x.Level);
                b.HasIndex(x => x.IsEnabled);
                b.HasIndex(x => new { x.Name, x.TenantId }).IsUnique();
            });

            // 配置告警记录实体
            builder.Entity<Alert>(b =>
            {
                b.ToTable("Alerts", "Matrix");

                b.ConfigureByConvention();

                b.Property(x => x.Title)
                    .IsRequired()
                    .HasMaxLength(500);

                b.Property(x => x.Message)
                    .IsRequired()
                    .HasMaxLength(2000);

                b.Property(x => x.Level)
                    .HasConversion<int>();

                b.Property(x => x.Status)
                    .HasConversion<int>();

                b.Property(x => x.TriggeredValue)
                    .HasPrecision(18, 6);

                b.Property(x => x.Dimensions)
                    .HasMaxLength(2000);

                b.Property(x => x.Assignee)
                    .HasMaxLength(200);

                b.Property(x => x.HandleNote)
                    .HasMaxLength(1000);

                b.Property(x => x.Tags)
                    .HasMaxLength(2000);

                // 配置索引
                b.HasIndex(x => x.AlertRuleId);
                b.HasIndex(x => x.Level);
                b.HasIndex(x => x.Status);
                b.HasIndex(x => x.StartTime);
                b.HasIndex(x => x.EndTime);
                b.HasIndex(x => new { x.Status, x.Level });
                b.HasIndex(x => new { x.AlertRuleId, x.Status });

                // 关系配置
                b.HasOne<AlertRule>()
                    .WithMany(r => r.Alerts)
                    .HasForeignKey(x => x.AlertRuleId)
                    .OnDelete(DeleteBehavior.Cascade);
            });

            // 配置全局查询过滤器（多租户支持）
            builder.Entity<Tenant>().HasQueryFilter(e => !EF.Property<bool>(e, "IsDeleted"));
            builder.Entity<TenantManagementService.Tenants.TenantConfiguration>().HasQueryFilter(e => !EF.Property<bool>(e, "IsDeleted"));
            builder.Entity<MonitoringMetric>().HasQueryFilter(e => !EF.Property<bool>(e, "IsDeleted"));
            builder.Entity<MonitoringMetricValue>().HasQueryFilter(e => !EF.Property<bool>(e, "IsDeleted"));
            builder.Entity<AlertRule>().HasQueryFilter(e => !EF.Property<bool>(e, "IsDeleted"));
            builder.Entity<Alert>().HasQueryFilter(e => !EF.Property<bool>(e, "IsDeleted"));

            // 配置租户隔离（如果启用多租户）
            if (typeof(IMultiTenant).IsAssignableFrom(typeof(Tenant)))
            {
                builder.Entity<Tenant>().Property<Guid?>("TenantId").HasColumnName("TenantId");
                builder.Entity<TenantManagementService.Tenants.TenantConfiguration>().Property<Guid?>("TenantId").HasColumnName("TenantId");
                builder.Entity<MonitoringMetric>().Property<Guid?>("TenantId").HasColumnName("TenantId");
                builder.Entity<MonitoringMetricValue>().Property<Guid?>("TenantId").HasColumnName("TenantId");
                builder.Entity<AlertRule>().Property<Guid?>("TenantId").HasColumnName("TenantId");
                builder.Entity<Alert>().Property<Guid?>("TenantId").HasColumnName("TenantId");
            }
        }
    }
}